package com.jic.market.impl.rest.discount.processor;

import com.jic.common.utils.IDUtils;
import com.jic.market.common.exception.MarketErrorCodeEnum;
import com.jic.market.common.exception.MarketException;
import com.jic.market.entity.PromotionRuleEntity;
import com.jic.market.enums.DiscountAmountServiceOperateEnum;
import com.jic.market.enums.DiscountDetailStatusEnum;
import com.jic.market.enums.FrontPromotionTypeEnum;
import com.jic.market.impl.rest.discount.model.ConditionDiscountModel;
import com.jic.market.impl.rest.discount.model.GoodsDetailModel;
import lombok.Data;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * @author yinhaijun
 * @date: 2020/4/27
 */
public abstract class AbstractConditionDiscountProcessor extends BaseDiscountProcessor {

    public void queryShoppingCart(ConditionDiscountModel conditionDiscountModel, Map<String, GoodsDetailModel> goodsDetailModelMap, Object request) {
        AbstractConditionDiscountProcessor.ConditionResult conditionResult = isCondition(conditionDiscountModel, goodsDetailModelMap, request, DiscountAmountServiceOperateEnum.SETTLEMENT_QUERY);
        if(!conditionResult.getPass()){

        }else {
            queryShoppingCartAfter(conditionResult, conditionDiscountModel, goodsDetailModelMap, request);
        }
    }

    public void querySettlement(ConditionDiscountModel conditionDiscountModel, Map<String, GoodsDetailModel> goodsDetailModelMap, Object request) {
        AbstractConditionDiscountProcessor.ConditionResult conditionResult = isCondition(conditionDiscountModel, goodsDetailModelMap, request, DiscountAmountServiceOperateEnum.SETTLEMENT_QUERY);
        if(!conditionResult.getPass()){
            if(conditionDiscountModel.getFrontPromotionTypeEnum() == FrontPromotionTypeEnum.COUPON_){
                throw new MarketException(MarketErrorCodeEnum.COUPON_NOT_USE, conditionResult.getMessage());
            }
        }else {
            // 运费
            conditionDiscountModel.calActualTotalFreightAmount(goodsDetailModelMap);
            querySettlementAfter(conditionResult, conditionDiscountModel, goodsDetailModelMap, request);
        }
    }

    public void create(ConditionDiscountModel conditionDiscountModel, Map<String, GoodsDetailModel> goodsDetailModelMap, Object request) {
        // 流水号生成
        conditionDiscountModel.setPromotionSerialNo(IDUtils.GenerateBillNo());
        conditionDiscountModel.setDiscountDetailStatusEnum(DiscountDetailStatusEnum.CREATE);
        // 对应商品的状态更改
        changeStatus(conditionDiscountModel, goodsDetailModelMap, DiscountDetailStatusEnum.CREATE);
        createAfter(conditionDiscountModel, goodsDetailModelMap, request);
    }

    public void pay(ConditionDiscountModel conditionDiscountModel, Map<String, GoodsDetailModel> goodsDetailModelMap, DiscountAmountServiceOperateEnum operateEnum, Object request) {
        conditionDiscountModel.setDiscountDetailStatusEnum(DiscountDetailStatusEnum.PAY);
        // 对应商品的状态更改
        changeStatus(conditionDiscountModel, goodsDetailModelMap, DiscountDetailStatusEnum.PAY);
        payAfter(conditionDiscountModel, goodsDetailModelMap, request);
    }

    public void cancel(ConditionDiscountModel conditionDiscountModel, Map<String, GoodsDetailModel> goodsDetailModelMap, List<String> cancelSkuList, Object request) {
        conditionDiscountModel.setDiscountDetailStatusEnum(DiscountDetailStatusEnum.REFUND);
        // 找出对应商品改状态
        List<String> thirdSkuIdList = conditionDiscountModel.getThirdSkuIdList();
        // 全退
        // 是否全退标记
        boolean isAllCancel = true;
        if(null == cancelSkuList || cancelSkuList.isEmpty()){
            changeStatus(conditionDiscountModel, goodsDetailModelMap, DiscountDetailStatusEnum.REFUND);
        }else {
            // 取两个集合的交集，该对应商品状态
            for(String thirdSkuId : thirdSkuIdList){
                if(cancelSkuList.contains(thirdSkuId)){
                    goodsDetailModelMap.get(thirdSkuId).setDiscountStatus(conditionDiscountModel, DiscountDetailStatusEnum.REFUND);
                }
            }
            for(String thirdSkuId : thirdSkuIdList){
                if(cancelSkuList.contains(thirdSkuId)){
                    GoodsDetailModel goodsDetailModel = goodsDetailModelMap.get(thirdSkuId);
                    if(goodsDetailModel.getDiscountStatus(conditionDiscountModel) != DiscountDetailStatusEnum.REFUND){
                        isAllCancel = false;
                    }
                }
            }
        }
        if(isAllCancel || null == cancelSkuList || cancelSkuList.isEmpty()){
            isAllCancelAfter(conditionDiscountModel, goodsDetailModelMap, request);
        }
    }

    /** 修改整个活动的状态 */
    private void changeStatus(ConditionDiscountModel conditionDiscountModel, Map<String, GoodsDetailModel> goodsDetailModelMap, DiscountDetailStatusEnum create) {
        List<String> thirdSkuIdList = conditionDiscountModel.getThirdSkuIdList();
        if (null != thirdSkuIdList && !thirdSkuIdList.isEmpty()) {
            thirdSkuIdList.forEach(thirdSkuId -> {
                GoodsDetailModel goodsDetailModel = goodsDetailModelMap.get(thirdSkuId);
                goodsDetailModel.setDiscountStatus(conditionDiscountModel, create);
            });
        }
    }

    public void isAllCancelAfter(ConditionDiscountModel conditionDiscountModel, Map<String, GoodsDetailModel> goodsDetailModelMap, Object request) {
    }

    protected void createAfter(ConditionDiscountModel conditionDiscountModel, Map<String, GoodsDetailModel> goodsDetailModelMap, Object request){
    }

    protected void payAfter(ConditionDiscountModel conditionDiscountModel, Map<String, GoodsDetailModel> goodsDetailModelMap, Object request){
    }

    protected void queryShoppingCartAfter(ConditionResult conditionResult, ConditionDiscountModel conditionDiscountModel, Map<String, GoodsDetailModel> goodsDetailModelMap, Object request){
    }

    protected void querySettlementAfter(ConditionResult conditionResult, ConditionDiscountModel conditionDiscountModel, Map<String, GoodsDetailModel> goodsDetailModelMap, Object request){
    }

    /** 是否符合优惠条件 */
    public abstract ConditionResult isCondition(ConditionDiscountModel conditionDiscountModel, Map<String, GoodsDetailModel> goodsDetailModelMap, Object request, DiscountAmountServiceOperateEnum operate);

    @Data
    public static class ConditionResult{
        private Boolean pass;
        private String message;
        // 用于判断总额
        private BigDecimal conditionTotalAmount;
        // 用于判断数量
        private BigDecimal conditionNum;
        private Object object;
        public ConditionResult(Boolean pass, String message){
            this.pass = pass;
            this.message = message;
        }
    }

//    /**
//     * 获取匹配成功的那条规则
//     * @param condition 传入的条件，比如额度、数量
//     * @param promotionRuleEntityList 条件规则
//     * @return
//     */
//    protected PromotionRuleEntity getFlightPromotionRuleEntity(BigDecimal condition, List<PromotionRuleEntity> promotionRuleEntityList) {
//        if(null != promotionRuleEntityList && !promotionRuleEntityList.isEmpty()){
//            PromotionRuleEntity promotionRuleEntity = null;
//            Integer level = -1;
//            for(int i = 0; i<promotionRuleEntityList.size();i++){
//                Integer conditionValue = promotionRuleEntityList.get(i).getConditionValue();
//                if(promotionRuleEntityList.get(i).getLevel() > level && condition.compareTo(new BigDecimal(conditionValue)) != -1){
//                    promotionRuleEntity = promotionRuleEntityList.get(i);
//                    level = promotionRuleEntityList.get(i).getLevel();
//                }
//            }
//            return promotionRuleEntity;
//
//        }
//        return null;
//    }

    // type 1金额、2折扣、3数量
    protected PromotionRuleEntity getFlightPromotionRuleEntity(BigDecimal condition, List<PromotionRuleEntity> promotionRuleEntityList, Integer type) {
        if(null != promotionRuleEntityList && !promotionRuleEntityList.isEmpty()){
            PromotionRuleEntity promotionRuleEntity = null;
            Integer level = -1;
            for(int i = 0; i<promotionRuleEntityList.size();i++){
                Long conditionValue = promotionRuleEntityList.get(i).getConditionValue();
                BigDecimal conditionValueTrue = null;
                if(type.equals(1)){
                    conditionValueTrue = new BigDecimal(conditionValue/100);
                }
                else if(type.equals(2)){
                    conditionValueTrue = new BigDecimal(conditionValue/10);
                }
                else if(type.equals(3)){
                    conditionValueTrue = new BigDecimal(conditionValue);
                }
                if(promotionRuleEntityList.get(i).getLevel() > level && condition.compareTo(conditionValueTrue) != -1){
                    promotionRuleEntity = promotionRuleEntityList.get(i);
                    level = promotionRuleEntityList.get(i).getLevel();
                }
            }
            return promotionRuleEntity;

        }
        return null;
    }

}
